package co.edu.usbcali.unidades.presentation.backingBeans;

import co.edu.usbcali.unidades.exceptions.*;
import co.edu.usbcali.unidades.modelo.*;
import co.edu.usbcali.unidades.modelo.dto.DivisionDTO;
import co.edu.usbcali.unidades.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.unidades.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.ext.HtmlSelectOneMenu;
import com.icesoft.faces.component.selectinputdate.SelectInputDate;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;

/**
 * 
 * 
 * @author Zathura Code Generator http://code.google.com/p/zathura
 * 
 */
public class DivisionView extends DataSource implements Renderable,
		DisposableBean {
	private HtmlInputText txtDivNombre;
	private HtmlInputText txtEstCodigo_Estado;
	private HtmlInputText txtUnrNit_UnidadResidencial;
	private HtmlInputText txtDivCodigo;
	private HtmlCommandButton btnSave;
	private HtmlCommandButton btnModify;
	private HtmlCommandButton btnDelete;
	private HtmlCommandButton btnClear;
	private boolean renderDataTable;
	private boolean flag = true;
	private RenderManager renderManager;
	private PersistentFacesState state = PersistentFacesState.getInstance();
	private List<Division> division;
	private List<DivisionDTO> divisionDTO;
	
	private HtmlSelectOneMenu cmbUnidades;
	private List<SelectItem> list_unidades = new ArrayList<SelectItem>();
	
	private HtmlInputText txtUnidadNombre = new HtmlInputText();
	

	private String nombreUni;
	
	String codUnidad="";

	public DivisionView() {
		super("");
	}

	public String action_clear() {
		txtDivNombre.setValue("");	
		return "";
	}

	public void listener_txtId(ValueChangeEvent event) {
		if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
			Division entity = null;

			try {
				String divCodigo = new String(txtDivCodigo.getValue()
						.toString());
				entity = BusinessDelegatorView.getDivision(divCodigo);
			} catch (Exception e) {
				// TODO: handle exception
			}

			if (entity == null) {
				txtDivNombre.setDisabled(false);
				txtEstCodigo_Estado.setDisabled(false);
				txtUnrNit_UnidadResidencial.setDisabled(false);
				txtDivCodigo.setDisabled(false);
				btnSave.setDisabled(false);
				btnDelete.setDisabled(true);
				btnModify.setDisabled(true);
				btnClear.setDisabled(false);
			} else {
				txtDivNombre.setValue(entity.getDivNombre());
				txtDivNombre.setDisabled(false);
				txtEstCodigo_Estado.setValue(entity.getEstado().getEstCodigo());
				txtEstCodigo_Estado.setDisabled(false);
				txtUnrNit_UnidadResidencial.setValue(entity
						.getUnidadResidencial().getUnrNit());
				txtUnrNit_UnidadResidencial.setDisabled(false);
				txtDivCodigo.setValue(entity.getDivCodigo());
				txtDivCodigo.setDisabled(true);
				btnSave.setDisabled(true);
				btnDelete.setDisabled(false);
				btnModify.setDisabled(false);
				btnClear.setDisabled(false);
			}
		}
	}

	public String action_save() {
		try {
			
			BusinessDelegatorView.saveDivision(null, txtDivNombre.getValue().toString().trim().toUpperCase(), "1", codUnidad);
			flag=true;
			renderManager.getOnDemandRenderer("DivisionView").requestRender();
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_delete() {
		try {
			BusinessDelegatorView.deleteDivision(FacesUtils
					.checkString(txtDivCodigo));
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYDELETED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_modify() {
		try {
			BusinessDelegatorView.updateDivision(null, FacesUtils
					.checkString(txtDivNombre).toUpperCase().trim(), 
					"1", 
					codUnidad);
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
			action_clear();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		return "";
	}

	public String action_modifyWitDTO(String divCodigo, String divNombre,
			String estCodigo_Estado, String unrNit_UnidadResidencial)
			throws Exception {
		try {
			BusinessDelegatorView.updateDivision(divCodigo, divNombre.toUpperCase(),
					estCodigo_Estado, unrNit_UnidadResidencial);
			renderManager.getOnDemandRenderer("DivisionView").requestRender();
			FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
		} catch (Exception e) {
			// renderManager.getOnDemandRenderer("DivisionView").requestRender();
			FacesUtils.addErrorMessage(e.getMessage());
			throw e;
		}

		return "";
	}

	public List<Division> getDivision() {
		if (flag) {
			try {
				division = BusinessDelegatorView.getDivision();
				flag = false;
			} catch (Exception e) {
				flag = true;
				FacesUtils.addErrorMessage(e.getMessage());
			}
		}

		return division;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setDivision(List<Division> division) {
		this.division = division;
	}

	public boolean isRenderDataTable() {
		try {
			if (flag) {
				if (BusinessDelegatorView.findTotalNumberDivision(nombreUni) > 0) {
					renderDataTable = true;
				} else {
					renderDataTable = false;
				}
			}

			flag = false;
		} catch (Exception e) {
			renderDataTable = false;
			e.printStackTrace();
		}

		return renderDataTable;
	}

	public DataModel getData() {
		state = PersistentFacesState.getInstance();

		if (onePageDataModel == null) {
			onePageDataModel = new LocalDataModel(pageSize);
		}

		return onePageDataModel;
	}

	/**
	 * This is where the Object data is retrieved from the database and returned
	 * as a list of objects for display in the UI.
	 */
	private DataPage<Division> getDataPage(int startRow, int pageSize) {
		// Retrieve the total number of objects from the database. This
		// number is required by the DataPage object so the paginator will know
		// the relative location of the page data.
		int totalNumberDivision = 0;

		try {
			totalNumberDivision = BusinessDelegatorView
					.findTotalNumberDivision(nombreUni).intValue();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Calculate indices to be displayed in the ui.
		int endIndex = startRow + pageSize;

		if (endIndex > totalNumberDivision) {
			endIndex = totalNumberDivision;
		}

		try {
			division = BusinessDelegatorView.findPageDivision(sortColumnName,
					sortAscending, startRow, endIndex - startRow, nombreUni);

			// Remove this Renderable from the existing render groups.
			// leaveRenderGroups();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Add this Renderable to the new render groups.
		// joinRenderGroups();
		// Reset the dirtyData flag.
		onePageDataModel.setDirtyData(false);
		// This is required when using Hibernate. If the SessionManager is not
		// cleared or closed objects are cached and stale objects will show up
		// in the table.
		// This way, the detached objects are reread from the database.
		// This call is not required with Hibernate, which uses a Query Hint
		// to clear the l2 cache in the DAO.
		flag = true;

		return new DataPage<Division>(totalNumberDivision, startRow, division);
	}

	public DataModel getDataDTO() {
		state = PersistentFacesState.getInstance();

		if (onePageDataModel == null) {
			onePageDataModel = new LocalDataModelDTO(pageSize);
		}

		return onePageDataModel;
	}

	/**
	 * This is where the Object data is retrieved from the database and returned
	 * as a list of objects for display in the UI.
	 */
	private DataPage<DivisionDTO> getDataPageDTO(int startRow, int pageSize) {
		// Retrieve the total number of objects from the database. This
		// number is required by the DataPage object so the paginator will know
		// the relative location of the page data.
		int totalNumberDivision = 0;

		try {
			totalNumberDivision = BusinessDelegatorView
					.findTotalNumberDivision(nombreUni).intValue();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Calculate indices to be displayed in the ui.
		int endIndex = startRow + pageSize;

		if (endIndex > totalNumberDivision) {
			endIndex = totalNumberDivision;
		}

		try {
			division = BusinessDelegatorView.findPageDivision(sortColumnName,
					sortAscending, startRow, endIndex - startRow, nombreUni);

			if (Utilities.validationsList(division)) {
				divisionDTO = new ArrayList<DivisionDTO>();

				for (Division divisionTmp : division) {
					DivisionDTO divisionDTO2 = new DivisionDTO();
					divisionDTO2.setDivCodigo(divisionTmp.getDivCodigo()
							.toString());
					divisionDTO2
							.setDivNombre((divisionTmp.getDivNombre() != null) ? divisionTmp
									.getDivNombre().toString()
									: null);
					divisionDTO2.setEstCodigo_Estado((divisionTmp.getEstado()
							.getEstCodigo() != null) ? divisionTmp.getEstado()
							.getEstCodigo().toString() : null);
					divisionDTO2
							.setUnrNit_UnidadResidencial((divisionTmp
									.getUnidadResidencial().getUnrNit() != null) ? divisionTmp
									.getUnidadResidencial().getUnrNit()
									.toString()
									: null);
					divisionDTO2.setDivision(divisionTmp);
					divisionDTO2.setDivisionView(this);
					divisionDTO.add(divisionDTO2);
				}
			}

			// Remove this Renderable from the existing render groups.
			leaveRenderGroups();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}

		// Add this Renderable to the new render groups.
		joinRenderGroups();
		// Reset the dirtyData flag.
		onePageDataModel.setDirtyData(false);
		// This is required when using Hibernate. If the SessionManager is not
		// cleared or closed objects are cached and stale objects will show up
		// in the table.
		// This way, the detached objects are reread from the database.
		// This call is not required with Hibernate, which uses a Query Hint
		// to clear the l2 cache in the DAO.
		flag = true;

		return new DataPage<DivisionDTO>(totalNumberDivision, startRow,
				divisionDTO);
	}

	protected boolean isDefaultAscending(String sortColumn) {
		return true;
	}

	/**
	 * This method is called when a render call is made from the server. Render
	 * calls are only made to views containing an updated record. The data is
	 * marked as dirty to trigger a fetch of the updated record from the
	 * database before rendering takes place.
	 */
	public PersistentFacesState getState() {
		onePageDataModel.setDirtyData();

		return state;
	}

	/**
	 * This method is called from faces-config.xml with each new session.
	 */
	public void setRenderManager(RenderManager renderManager) {
		this.renderManager = renderManager;
	}

	public void renderingException(RenderingException arg0) {
		if (arg0 instanceof TransientRenderingException) {
		} else if (arg0 instanceof FatalRenderingException) {
			// Remove from existing Customer render groups.
			leaveRenderGroups();
		}
	}

	/**
	 * Remove this Renderable from existing uiCustomerBeans render groups.
	 * OnDemandRenderers are named/created using the underlying Customer Number.
	 */
	private void leaveRenderGroups() {
		if (Utilities.validationsList(divisionDTO)) {
			for (DivisionDTO divisionTmp : divisionDTO) {
				renderManager.getOnDemandRenderer("DivisionView").remove(this);
			}
		}
	}

	/**
	 * Add this Renderable to the new uiCustomerBeans render groups.
	 * OnDemandRenderers are named/created using the underlying Customer Number.
	 */
	private void joinRenderGroups() {
		if (Utilities.validationsList(divisionDTO)) {
			for (DivisionDTO divisionTmp : divisionDTO) {
				renderManager.getOnDemandRenderer("DivisionView").add(this);
			}
		}
	}

	public void dispose() throws Exception {
	}

	public RenderManager getRenderManager() {
		return renderManager;
	}

	public void setState(PersistentFacesState state) {
		this.state = state;
	}

	public HtmlInputText getTxtDivNombre() {
		return txtDivNombre;
	}

	public void setTxtDivNombre(HtmlInputText txtDivNombre) {
		this.txtDivNombre = txtDivNombre;
	}

	public HtmlInputText getTxtEstCodigo_Estado() {
		return txtEstCodigo_Estado;
	}

	public void setTxtEstCodigo_Estado(HtmlInputText txtEstCodigo_Estado) {
		this.txtEstCodigo_Estado = txtEstCodigo_Estado;
	}

	public HtmlInputText getTxtUnrNit_UnidadResidencial() {
		return txtUnrNit_UnidadResidencial;
	}

	public void setTxtUnrNit_UnidadResidencial(
			HtmlInputText txtUnrNit_UnidadResidencial) {
		this.txtUnrNit_UnidadResidencial = txtUnrNit_UnidadResidencial;
	}

	public HtmlInputText getTxtDivCodigo() {
		return txtDivCodigo;
	}

	public void setTxtDivCodigo(HtmlInputText txtDivCodigo) {
		this.txtDivCodigo = txtDivCodigo;
	}

	public HtmlCommandButton getBtnSave() {
		return btnSave;
	}

	public void setBtnSave(HtmlCommandButton btnSave) {
		this.btnSave = btnSave;
	}

	public HtmlCommandButton getBtnModify() {
		return btnModify;
	}

	public void setBtnModify(HtmlCommandButton btnModify) {
		this.btnModify = btnModify;
	}

	public HtmlCommandButton getBtnDelete() {
		return btnDelete;
	}

	public void setBtnDelete(HtmlCommandButton btnDelete) {
		this.btnDelete = btnDelete;
	}

	public HtmlCommandButton getBtnClear() {
		return btnClear;
	}

	public void setBtnClear(HtmlCommandButton btnClear) {
		this.btnClear = btnClear;
	}

	public void setRenderDataTable(boolean renderDataTable) {
		this.renderDataTable = renderDataTable;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public List<DivisionDTO> getDivisionDTO() {
		return divisionDTO;
	}

	public void setDivisionDTO(List<DivisionDTO> divisionDTO) {
		this.divisionDTO = divisionDTO;
	}
	
	public TimeZone getTimeZone() {
		return java.util.TimeZone.getDefault();
	}	

	public String getNombreUni() {		
		return nombreUni;
	}

	public void setNombreUni(String nombreUni) {
		this.nombreUni = nombreUni;
	}
	

	public HtmlSelectOneMenu getCmbUnidades() {
		
		list_unidades.clear();
		List<UnidadResidencial> unidades;
		try {
			unidades = BusinessDelegatorView.getUnidadesAdmin((FacesUtils.getSession().getAttribute("codAdminLoc")).toString());
			SelectItem item = new SelectItem(-1, "--Seleccione Una Unidad--");
			list_unidades.add(item);
			for (int i = 0; i < unidades.size(); i++) {
				if (unidades.get(i).getEstado().getEstCodigo().equals("1")) {
					item = new SelectItem(unidades.get(i).getUnrNit(), unidades
							.get(i).getUnrNombre());
					list_unidades.add(item);
				}
			}
			
		} catch (Exception e) {
			
		}
		return cmbUnidades;
	}

	public void setCmbUnidades(HtmlSelectOneMenu cmbUnidades) {
		this.cmbUnidades = cmbUnidades;
	}
	
	public List<SelectItem> getList_unidades() {
		return list_unidades;
	}

	public void setList_unidades(List<SelectItem> listUnidades) {
		list_unidades = listUnidades;
	}
	
	public HtmlInputText getTxtUnidadNombre() {		
		UnidadResidencial unidad;
		if(division!=null){
			division.clear();
		}
		try {
			unidad = BusinessDelegatorView.getUnidadResidencial(FacesUtils.getSession().getAttribute("unidadNit").toString());
			txtUnidadNombre.setValue(unidad.getUnrNombre());			
			nombreUni=unidad.getUnrNombre();
			codUnidad=unidad.getUnrNit();
			flag=true;
			renderManager.getOnDemandRenderer("DivisionView").requestRender();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());			
		}
		return txtUnidadNombre;
	}

	public void setTxtUnidadNombre(HtmlInputText txtUnidadNombre) {
		this.txtUnidadNombre = txtUnidadNombre;
	}




	/**
	 * A special type of JSF DataModel to allow a datatable and datapaginator to
	 * page through a large set of data without having to hold the entire set of
	 * data in memory at once. Any time a managed bean wants to avoid holding an
	 * entire dataset, the managed bean declares this inner class which extends
	 * PagedListDataModel and implements the fetchData method. fetchData is
	 * called as needed when the table requires data that isn't available in the
	 * current data page held by this object. This requires the managed bean
	 * (and in general the business method that the managed bean uses) to
	 * provide the data wrapped in a DataPage object that provides info on the
	 * full size of the dataset.
	 */
	private class LocalDataModel extends PagedListDataModel {
		public LocalDataModel(int pageSize) {
			super(pageSize);
		}

		public DataPage<Division> fetchPage(int startRow, int pageSize) {
			// call enclosing managed bean method to fetch the data
			return getDataPage(startRow, pageSize);
		}
	}

	private class LocalDataModelDTO extends PagedListDataModel {
		public LocalDataModelDTO(int pageSize) {
			super(pageSize);
		}

		public DataPage<DivisionDTO> fetchPage(int startRow, int pageSize) {
			// call enclosing managed bean method to fetch the data
			return getDataPageDTO(startRow, pageSize);
		}
	}

	public void listener_cargarUnidadRes(ValueChangeEvent ev) {
		UnidadResidencial u=null;
		try {
			if(!cmbUnidades.getValue().toString().equals("-1")){
				btnSave.setDisabled(false);
			}else{
				btnSave.setDisabled(true);				
			}
			u = BusinessDelegatorView.getUnidadResidencial(cmbUnidades.getValue().toString());
			System.out.println("selecciono "+ cmbUnidades.getValue().toString());
			if(u!=null){
				nombreUni = u.getUnrNombre();
				flag=true;
				isRenderDataTable();
			}
						
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
		
}
